#[cfg(test)]
use actix_web::{App, test, web};
#[cfg(test)]
use actix_web::dev::{Service, ServiceResponse};
#[cfg(test)]
use actix_web::test::read_body;
#[cfg(test)]
use surrealdb::engine::local::{Db};
#[cfg(test)]
use surrealdb::Surreal;
#[cfg(test)]
use crate::common::global_config::AppState;

#[cfg(test)]
pub fn init_logger() {
    let _ = env_logger::builder()
        .filter_level(log::LevelFilter::Debug)
        .is_test(true)
        .try_init();
}

#[cfg(test)]
pub async fn init_test_db() -> Surreal<Db> {
    let db = Surreal::new::<surrealdb::engine::local::Mem>(()).await.unwrap();
    db.use_ns("test").use_db("test").await.unwrap();
    db
}

#[cfg(test)]
pub async fn init_test_app_with_db<F>(db: Surreal<Db>, configure_fn: F) -> impl Service<actix_http::Request, Response=ServiceResponse, Error=actix_web::Error>
where
    F: FnOnce(&mut web::ServiceConfig) + Send + 'static,
{
    let app_state = web::Data::new(AppState::new_with_db(db));
    test::init_service(App::new()
        .app_data(app_state.clone())
        .configure(configure_fn)
    ).await
}

#[cfg(test)]
pub async fn init_test_app<F>(configure_fn: F) -> impl Service<actix_http::Request, Response=ServiceResponse, Error=actix_web::Error>
where
    F: FnOnce(&mut web::ServiceConfig) + Send + 'static,
{
    let db = init_test_db().await;
    init_test_app_with_db(db, configure_fn).await
}

#[cfg(test)]
pub async fn resolve_response(res: ServiceResponse) -> String {
    let body = read_body(res).await;
    let body = String::from_utf8_lossy(&body);
    body.to_string()
}